Java Database Programming with JDBC Java Database Programming with JDBC
by Pratik Patel
Coriolis, The Coriolis Group
ISBN: 1576100561   Pub Date: 10/01/96
  

Table of Contents


Appendices

APPENDIX A
Java Language Fundamentals

If you are already familiar with programming, especially C or C++ programming, this appendix should serve as a good hands-on review. As we discuss Java, we’ll point out the areas in which Java differs from other languages. If you don’t have much experience using structured programming languages, this appendix will give you a good overview of the basic components required to make programming languages like Java come alive.

The actual language components featured in this appendix include:

  Comments
  Identifiers
  Keywords
  Data types
  Variable declarations

What Makes A Java Program?

Before we get into the details of each Java language component, let’s stand back 10 steps and look at how many of the key language components are used in the context of a Java program. Figure A.1(shown later) presents a complete visual guide. Here, we’ve highlighted components such as variable declarations, Java keywords, operators, literals, expressions, and control structures.


Figure A.1  A visual guide to the key Java language components.


Figure A.1  Continued

In case you’re wondering, the output for this program looks like this:

Hello John my name is Anthony
That's not my name!
Let's count to ten....
1 2 3 4 5 6 7 8 9 10
Now down to zero by two.
10 8 6 4 2 0
Finally, some arithmetic:
10 * 3.09 = 30.9
10 * 3.09 = 30 (integer cast)
10 / 3.09 = 3.23625
10 / 3.09 = 3 (integer cast)

Lexical Structure

The lexical structure of a language refers to the elements of code that make the code easy for us to understand, but have no effect on the compiled code. For example, all of the comments you place in a program to help you understand how it works are ignored by the Java compiler. You could have a thousand lines of comments for a 20-line program and the compiled bytecodes for the program would be the same size if you took out all the comments. This does not mean that all lexical structures are optional. It simply means that they do not effect the bytecodes.

The lexical structures we’ll discuss include:

  Comments
  Identifiers
  Keywords
  Separators

Comments

Comments make your code easy to understand, modify, and use. But adding comments to an application only after it is finished is not a good practice. More often than not, you won’t remember what the code you wrote actually does after you get away from it for a while. Unfortunately, many programmers follow this time-honored tradition. We suggest you try to get in the habit of adding comments as you write your code.

Java supports three different types of comment styles. The first two are taken directly from C and C++. The third type of comment is a new one that can be used to automatically create class and method documentation.

Comment Style #1

/* Comments here... */

This style of commenting comes to us directly from C. Everything between the initial slash-asterisk and ending asterisk-slash is ignored by the Java compiler. This style of commenting can be used anywhere in a program, even in the middle of code (not a good idea). This style of commenting is useful when you have multiple lines of comments because your comment lines can wrap from one line to the next, and you only need to use one set of the /* and */ symbols. Examples:

/*
This program was written by Joe Smith.
It is the greatest program ever written!
*/

while (i <= /* comments can be placed here */ maxnum)
{
   total += i;
   i++;
}

In the second example, the comment line is embedded within the program statement. The compiler skips over the comment text, and thus the actual line of code would be processed as:

while (i <= maxnum)
...

Programmers occasionally use this style of commenting while they are testing and debugging code. For example, you could comment out part of an equation or expression:

sum = i /* + (base - 10) */ + factor;

Comment Style #2

// Comment here...

This style of commenting is borrowed from C++. Everything after the double slash marks is ignored by the Java compiler. The comment is terminated by a line return, so you can’t use multiple comment lines unless you start each line with the double-slash. Examples:

// This program was written by Joe Smith.
// It is the greatest program ever written!

while (i <= // this won't work maxnum)
{
   total += i;
   i++;
}

base = 20;
// This comment example also won't work because the Java
   compiler will treat this second line as a line of code
value = 50;

The comment used in the second example won’t work like you might intend because the remainder of the line of code would be commented out (everything after i <=). In the third example, the second comment line is missing the starting // symbols, and the Java compiler will get confused because it will try to process the comment line as if it were a line of code. Believe it or not, this type of commenting mistake occurs often—so watch out for it!

Comment Style #3

/** Doc Comment here... */

This comment structure may look very similar to the C style of commenting, but that extra asterisk at the beginning makes a huge difference. Of course, remember that only one asterisk must be used as the comment terminator. The Java compiler still ignores the comment, but another program called JAVADOC.EXE, which ships with the Java Development Kit, uses these comments to construct HTML documentation files that describe your packages, classes, and methods, as well as all the variables they use.

Let’s look at the third style of commenting in more detail. If implemented correctly and consistently, this style of commenting can provide you with numerous benefits. Figure A.2 shows what the output of the JAVADOC program looks like when run on a typical Java source file.


Figure A.2  Sample output from the JAVADOC program.

If you have ever looked at the Java API documentation on Sun’s Web site, Figure A.2 should look familiar to you. In fact, the entire API documentation was created this way.

JAVADOC will work if you have created comments or not. Figure A.3 shows the output from this simple application:

class HelloWorld {
   public static void main(String args[]) {
      System.out.println("Hello World");
   }
}


Figure A.3  Sample output from the JAVADOC program.

To add a little more information to our documentation, all we have to do is add this third style of comments. If we change the little HelloWorld application and add a few key comments, the code will look like this:

/**
 * Welcome to HelloWorld
 * @author Anthony Potts
 * @version 1.1
 * @see java.lang.System
 */
class helloworld {
   /**
    * Main method of helloworld
    */
   public static void main(String args[]) {
      System.out.println("Hello World!");
   }
}

If you now run JAVADOC, the browser will display what you see in Figure A.4. As you can see, this gives us much more information. This system is great for producing documentation for public distribution. Just like all comments, though, it is up to you to make sure that the comments are accurate and plentiful enough to be helpful. Table A.1 lists the tags you can use in your class comments.


Figure A.4  The new JAVADOC output.

Table A.1 Tags for class comments.
Tag Description
@see classname Adds a hyperlinked “See Also” to your class; the classname can be any other class
@see fully-qualified-classname Also adds a “See Also” to the class, but this time you need to use a fully qualified class name like “java.awt.window”
@see fully-qualified-classname#methodname Also adds a “See Also” to the class, but now you are pointing to a specific method within that class
@version version-text Adds a version number that you provide; the version number can be numbers or text
@author author-name Adds an author entry; you can use multiple author tags
The tags you can use in your method comments include all of the “@see” tags as well as the following:
@param paramter-name description... Used to show which parameters the method accepts; multiple “@param” tags are acceptable
@return description... Used to describe what the method returns
@exception fully-qualified-classname description... Used to add a “throw” entry that describes what type of exceptions this method can throw; multiple “@exception” tags are acceptable

Identifiers

Identifiers are the names used for variables, classes, methods, packages, and interfaces which allow the compiler to distinguish them. Identifiers in the Java language should always begin with a letter of the alphabet, either upper or lower case. The only exceptions to this rule are the underscore symbol (_) and the dollar sign ($), which may also be used. If you try to use any other symbol or a numeral as the initial character, you will receive an error.

After the initial character, you are allowed to use numbers, but not all symbols. You can also use almost all of the characters from the Unicode character set. If you are not familiar with the Unicode character set or you get errors, we suggest that you stick with the standard alphabetic characters.

The length of an identifier is basically unlimited. We managed to get up to a few thousand characters before we got bored. It’s doubtful you will ever need that many characters, but it is nice to know that the Java compiler won’t limit you if you want to create long descriptive names. The only limit you may encounter involves creating class names. Since class names are also used as file names, you need to create names that will not cause problems with your operating system or anyone who will be using your program.

You must also be careful not to use any of the special Java keywords listed in the next section. Here are some examples of valid identifiers:

HelloWorld     $Money       TickerTape
_ME2           Chapter3     ABC123

And here are some examples of invalid identifiers:

3rdChapter     #Hello       -Main

Common Errors When Using Identifiers

As you are defining and using identifiers in your Java programs, you are bound to encounter some errors from time to time. Let’s look at some of the more common error messages that the Java compiler displays. Notice that we’ve included the part of the code that is responsible for generating the error, the error message, and a description of the message so that you can make sense of it.

Code Example:

public class 1test {
}

Error Message:

D:\java\lib\test.java:1: Identifier expected.

Description:

An invalid character has been used in the class identifier. You will see this error when the first character is invalid (especially when it is a number).

Code Example:

public class te?st {
}

Error Message:

D:\java\lib\test.java:1: '{' Expected

Description:

This is a common error that occurs when you have an invalid character in the middle of an identifier. In this case, the question mark is invalid, so the compiler gets confused where the class definition ends and its implementation begins.

Code Example:

public class #test {
}

Error Message:

D:\java\lib\test.java:1: Invalid character in input.

Description:

Here, the error stems from the fact that the initial character is invalid.

Code Example:

public class catch {
}

Error Message:

D:\java\lib\test.java:1: Identifier expected.

Description:

This error shows up when you use a protected keyword as an identifier.

Keywords

In Java, like other languages, there are certain keywords or “tokens” that are reserved for system use. These keywords can’t be used as names for your classes, variables, packages, or anything else. The keywords are used for a number of tasks such as defining control structures (if, while, and for) and declaring data types (int, char, and float). Table A.2 provides the complete list of Java keywords.

Table A.2 Java language keywords.
Keyword Description
abstract Class modifier
boolean Used to define a boolean data type
break Used to break out of loops
byte Used to define a byte data type
byvalue * Not implemented yet
cast Used to translate from type to type
catch Used with error handling
char Used to define a character data type (16-bit)
class Used to define a class structure
const * Not implemented yet
continue Used to continue an operation
default Used with the switch statement
do Used to create a do loop control structure
Double Used to define a floating-point data type (64-bit)
else Used to create an else clause for an if statement
extends Used to subclass
final Used to tell Java that this class can not be subclassed
finally Used with exceptions to determine the last option before exiting; it guarantees that code gets called if an exception does or does not happen
float Used to define a floating-point data type (32-bit)
for Used to create a for loop control structure
future * Not implemented yet
generic * Not implemented yet
goto * Not implemented yet
if Used to create an if-then decision-making control structure
implements Used to define which interfaces to use
import Used to reference external Java packages
inner Used to create control blocks
instanceof Used to determine if an object is of a certain type
int Used to define an integer data type (32-bit values)
interface Used to tell Java that the code that follows is an interface
interfacelong Used to define an integer data type (64-bit values)
native Used when calling external code
new Operator used when creating an instance of a class (an object)
null Reference to a non-existent value
operator * Not implemented yet
outer Used to create control blocks
package Used to tell Java what package the following code belongs to
private Modifier for classes, methods, and variables
protected Modifier for classes, methods, and variables
public Modifier for classes, methods, and variables
rest * Not implemented yet
return Used to set the return value of a class or method
short Used to define an integer data type (16-bit values)
static Modifier for classes, methods, and variables
super Used to reference the current class’ parent class
switch Block statement used to pick from a group of choices
synchronized Modifier that tells Java that only one instance of a method can be run at one time; it keeps Java from running the method a second time before the first is finished; it is especially useful when dealing with files to avoid conflicts
this Used to reference the current object
throw Statement that tells Java what exception to pass on an error
transient Modifier that can access future Java code
try Operator that is used to test for exceptions in code
var * Not implemented yet
void Modifier for setting the return value of a class or method to nothing
volatile Variable modifier
while Used to create a while loop control structure

The words marked with an asterisk (*) are not currently used in the Java language, but you still can’t use them to create your own identifiers. More than likely, they will be used as keywords in future versions of the Java language.

Literals

Literals are the values that you assign when entering explicit values. For example, in an assignment statement like this the value 10 is a literal. But do not get literals confused with types. Even though they usually go hand in hand, literals and types are not the same.

i = 10;

Types are used to define what type of data a variable can hold, while literals are the values that are actually assigned to those variables.

Literals come in three flavors: numeric, character, and boolean. Boolean literals are simply True and False.

Numeric Literals

Numeric literals are just what they sound like—numbers. We can further subdivide the numeric literals into integers and floating-point literals.

Integer literals are usually represented in decimal format, although you can use the hexadecimal and octal format in Java. If you want to use the hexadecimal format, your numbers need to begin with an 0x or 0X. Octal integers simply begin with a zero (0).

Integer literals are stored differently depending on their size. The int data type is used to store 32-bit integer values ranging from -2,147,483,648 to 2,147,483,648 (decimal). If you need to use even larger numbers, Java switches over to the long data type, which can store 64 bits of information for a range of - 9.223372036855e+18 to 9.223372036855e+18. This would give you a number a little larger than 9 million trillion—enough to take care of the national debt! To specify a long integer, you will need to place an “l” or “L” at the end of the number. Don’t get confused by our use of the terms int and long. There are many other integer data types used by Java, but they all use int or long literals to assign values. Table A.3 provides a summary of the two integer literals.

Table A.3 Summary of integer literals.
Integer Literals Ranges Negative Minimum Positive Maximum
int data type -2,147,483,648 2,147,483,648
long data type -9.223372036855e+18 9.223372036855e+18

Here are some examples of how integer literals can be used to assign values in Java statements:

int i;
i = 1;  // All of these literals are of the integer type
i= -9;
i = 1203131;

i = 0xA11;   // Using a hexadecimal literal
i = 07543;   // Using an octal literal

i = 4.5;     // This would be illegal because a floating-point
             // literal can't be assigned to an integer type
long lg;
lg = 1L;     // All of these literals are of the long
             // integer type
lg = -9e15;
lg = 7e12;

The other type of numeric literal is the floating-point literal. Floating-point values are any numbers that have anything to the right of the decimal place. Similar to integers, floating-point values have 32-bit and 64-bit representations. Both data types conform to IEEE standards. Table A.4 provides a summary of the two floating-point literals.

Table A.4 Summary of floating-point literals.
Floating-Point Ranges Negative Minimum Positive Maximum
float data type 1.40239846e-45 3.40282347e38
double data type 4.94065645841246544e-324 1.79769313486231570e308

Here are some examples of how floating-point literals can be used to assign values in Java statements:

float f;
f = 1.3;  // All of these literals are of the floating-point
          // type float (32-bit)
f = -9.0;
f = 1203131.1241234;


double d;
d = 1.0D;  // All of these literals are of the floating-
           // point type double(32-bit)
d = -9.3645e235;
d = 7.0001e52D;

Character Literals

The second type of literal that you need to know about is the character literal. Character literals include single characters and strings. Single character literals are enclosed in single quotation marks, while string literals are enclosed in double quotes.

Single characters can be any one character from the Unicode character set. There are also a few special two-character combinations that are non-printing characters but which perform important functions. Table A.5 shows these special combinations.

Table A.5 Special character combinations in Java.
Character Combination Standard Designation Description
\ <newline> Continuation
\n NL or LF New Line
\b BS Backspace
\r CR Carriage Return
\f FF Form Feed
\t HT Horizontal Tab
\\ \ Backslash
\’ Single Quote
\” Double Quote
\xdd 0xdd Hex Bit Pattern
\ddd 0ddd Octal Bit Pattern
\uddd 0xdddd Unicode Character

The character combinations from Table A.5 also apply to strings. Here are some examples of how character and string literals can be used in Java statements:

char ch;
ch = 'a';   // All of these literals are characters
ch = \n;    // Assign the newline character
ch = \';    // Assign a single quote
ch = \x30;  // Assign a hexadecimal character code

String str;
str = "Java string";

Operators

Operators are used to perform computations on one or more variables or objects. You use operators to add values, compare the size of two numbers, assign a value to a variable, increment the value of a variable, and so on. Table A.6 lists the operators used in Java. Later in this appendix, we’ll explain in detail how each operator works, and we’ll also explain operator precedence.

Table A.6 Operators used in Java.
Operator Description
+ Addition
- Subtraction
* Multiplication
/ Division
% Modulo
++ Increment
Decrement
> Greater than
>= Greater than or equal to
< Less than
<= Less than or equal to
== Equal to
!= Not equal to
! Logical NOT
&& Logical AND
|| Logical OR
& Bitwise AND
^ Bitwise exclusive OR
| Bitwise OR
~ Bitwise complement
<< Left shift
>> Right shift
>>> Zero fill right shift
= Assignment
+= Assignment with addition
-= Assignment with subtraction
*= Assignment with multiplication
/= Assignment with division
%= Assignment with modulo
&= Assignment with bitwise AND
|= Assignment with bitwise OR
^= Assignment with bitwise exclusive OR
<<= Assignment with left shift
>>= Assignment with right shift
>>>= Assignment with zero fill right shift

Separators

Separators are used in Java to delineate blocks of code. For example, you use curly brackets to enclose a method’s implementation, and you use parentheses to enclose arguments being sent to a method. Table A.7 lists the seperators used in Java.

Table A.7 Separators used in Java.
Separator Description
( ) Used to define blocks of arguments
[ ] Used to define arrays
{ } Used to hold blocks of code
, Used to separate arguments or variables in a declaration
; Used to terminate lines of contiguous code

Types And Variables

Many people confuse the terms types and variables, and use them synonymously. They are, however, not the same. Variables are basically buckets that hold information, while types describe what type of information is in the bucket.

A variable must have both a type and an identifier. Later in this appendix we will cover the process of declaring variables. For now, we just want to guide you through the details of how to decide which types to use, and how to use them properly.

Similar to literals, types can be split into several different categories, including the numeric types—byte, short, int, long, float, and double—and the char and boolean types. We will also discuss the string type. Technically, the string type is not a type—it is a class. However, it is used so commonly that we decided to include it here.

All of the integer numeric types use signed two’s-complement integers for storing data. Table A.8 provides a summary of the ranges for each of the key Java datatypes.

Table A.8 Summary of the Java datatypes.
Data Type Negative Minimal Positive Maximal
byte -256 255
short -32768 32767
int -2147483648 2147483647
long -9223372036854775808 9223372036854775807
float 1.40239846e-45 3.40282347e38
double 4.94065645841246544e-324 1.79769313486231570e308
boolean False True

byte

The byte type can be used for variables whose value falls between -256 and 255. byte types have an 8-bit length. Here are some examples of byte values:

-7     5       238

short

The short numeric type can store values ranging from -32768 to 32767. It has a 16-bit depth. Here are some examples:

-7     256     -29524

int

The int data type takes the short type to the next level. It uses a 32-bit signed integer value that takes our minimal and maximal value up to over 2 billion. Because of this tremendous range, it is one of the most often used datatypes for integers.

Often, unskilled programmers will use the int datatype even though they don’t need the full resolution that this datatype provides. If you are using smaller integers, you should consider using the short data type. The rule of thumb to follow is if you know exactly the range of values a certain variable will store, use the smallest datatype possible. This will let your program use less memory and therefore run faster, especially on slower machines or machines with limited RAM.

Here are some examples of int values:

-7     256     -29523234     1321412422

long

The long data type is the mother of all integer types. It uses a full 64-bit data path to store values that reach up to over 9 million trillion. But be extremely careful when using variables of the long type. If you start using too many of them, or God forbid, an array of longs, you can quickly eat up a ton of resources.


Tip:  The danger of using long.
Java provides useful garbage collection tools, so when you are done with these large data types, they will be disposed of and their resources reclaimed. But if you are creating large arrays of long integers, you could really be asking for trouble. For example, if you created a two-dimensional array of long integers that had a 100x100 grid, you would be using up about 100 kilobytes of memory.

Here are some examples of long values:

-7     256     -29523234     1.835412e15     -3e18

float

The float data type is one of two types used to store floating-point values. The float type is compliant with the IEEE 754 conventions. The floating-point types of Java can store gargantuan numbers. We do not have enough room on the page to physically show you the minimal and maximal values the float data type can store, so we will use a little bit of tricky sounding lingo taken from the Java manual:

The finite nonzero values of type float are of the form s * m * 2e, where s is +1 or -1, m is a positive integer less than 2^24 and e is an integer between -149 and 104, inclusive.

Whew, that’s a mouthful. Here are a few examples to show you what the float type might look like in actual use:

-7F     256.0     -23e34     23e100

double

As if the float type could not hold enough, the double data type gives you even bigger storage space. Let’s look again at Sun’s definition of the possible values for a double:

The finite nonzero values of type float are of the form s * m * 2e, where s is +1 or -1, m is a positive integer less than 2^53 and e is an integer between -1045 and 1000, inclusive.

Again, you can have some truly monstrous numbers here. But when you start dealing with hardcore programming, this type of number becomes necessary from time to time, so it is wise to understand its ranges. Here are a few examples:

-7.0D     256.0D     -23e424     23e1000

boolean

In other languages, the boolean data type has been designated by an integer with a nonzero or zero value to represent True and False, respectively. This method works well because it gives the user the ability to check for all kinds of values and perform expressions like this:

x=2;
if x then...

This can be handy when performing parsing operations or checking string lengths. In Java, however, the boolean data type has its own True and False literals that do not correspond to other values. In fact, as you will learn later in this appendix, Java does not even allow you to perform casts between the boolean data type and any others. There are ways around this limitation, and we will discuss them when we talk about conversion methods.

char

The char data type is used to store single characters. Since Java uses the Unicode character set, the char type needs to be able to store thousands of characters, so it uses a 16-bit signed integer. The char data type has the ability to be cast or converted to almost all of the others, as we will show you in the next section.

string

The string type is actually not a primitive data type; it is a class all its own. We decided to talk a little about it here because it is so commonly used that it might as well be considered a primitive. In C and C++, strings are stored in arrays of chars. Java does not use the char type for this, but instead has created its own class that handles strings.

One big advantage to using a class instead of an array of char types is that we are more or less unlimited in the amount of information we can place in a string variable. In C++, the array of chars was limited; now that limitation is taken care of within the class, where we do not care how it is handled.

Variable Declarations

Declaring variables in Java is very similar to declaring variables in C/C++, as long as you are using the primitive data types. As we said before, almost everything in Java is a class—except the primitive data types. Let’s look at how primitive data types are declared.

Here is what a standard declaration for a primitive variable might look like:

int  i;

We have just declared a variable “i” to be an integer. Here are a few more examples:

byte i, j;
int a=7, b = a;
float f = 1.06;
String name = "Tony";

These examples illustrate some of the things you can do while declaring variables. Let’s look at each one individually.

int  i;

This is the most basic declaration, with the data type followed by the variable you are declaring.

byte i, j;

In this example, we are declaring two byte variables at one time. There is no limit to the number of variables you can declare this way. All you have to do is add a comma between each variable you wish to declare of the given type, and Java takes care of it for you.

You also have the ability to assign values to variables as you declare them. You can even use a variable you are declaring as part of an expression for the declaration of another variable in the same line. Before we confuse you more, here is an example:

int i = 1;
int j = i, k= i + j;

Here we have first declared a variable i as int and assigned it a value of 1. In the next line, we start by declaring a variable j to be equal to i. This is perfectly legal. Next, on the same line, we declare a variable k to be equal to i plus j. Once again, Java handles this without a problem. We could even shorten these two statements to one line like this:

int i = 1, j = i, k= i + j;

One thing to watch out for is using variables before they have been declared. Here’s an example:

int j = i, k= i + j;  // i is not defined yet
int i = 1;

This would cause an “undefined variable” error because Java does not know to look ahead for future declarations. Let’s look at another example:

float f = 1.06;

Does this look correct? Yes, but it’s not. This is a tricky one. By default, Java assumes that numbers with decimal points are of type double. So, when you try and declare a float to be equal to this number, you receive the following error:

Incompatible type for declaration. Explicit cast needed to convert double
to float.

Sounds complicated, but all this error message means is that you need to explicitly tell Java that the literal value 1.06 is a float and not a double. There are two ways to accomplish this. First, you can cast the value to a float like this:

float f = (float)1.06;

This works fine, but it can get confusing. Java also follows the convention used by other languages of placing an “f” at the end of the literal value to indicate explicitly that it is a float. This also works for the double data type, except that you would use a “d.” (By the way, capitalization of the f and d does not make a difference.)

float f = 1.06f;
double d = 1.06d;

You should realize that the “d” is not needed in the double declaration because Java assumes it. However, it is better to label all of your variables when possible, especially if you are not sure.

Using Arrays

It’s difficult to imagine creating any large application or applet without having an array or two. Java uses arrays in a much different manner than other languages. Instead of being a structure that holds variables, arrays in Java are actually objects that can be treated just like any other Java object.

The powerful thing to realize here is that because arrays are objects that are derived from a class, they have methods you can call to retrieve information about the array or to manipulate the array. The current version of the Java language only supports the length method, but you can expect that more methods will be added as the language evolves.

One of the drawbacks to the way Java implements arrays is that they are only one-dimensional. In most other languages, you can create a two-dimensional array by just adding a comma and a second array size. In Java, this does not work. The way around this limitation is to create an array of arrays. Because this is easy to do, the lack of built-in support for multi-dimensional arrays shouldn’t hold you back.

Declaring Arrays

Since arrays are actually instances of classes (objects), we need to use constructors to create our arrays much like we did with strings. First, we need to pick a variable name, declare it as an array object, and specify which data type the array will hold. Note that an array can only hold a single data type—you can’t mix strings and integers within a single array. Here are a few examples of how array variables are declared:

int    intArray[];
String   Names[];

As you can see, these look very similar to standard variable declarations, except for the brackets after the variable name. You could also put the brackets after the data type if you think this approach makes your declarations more readable:

int[] intArray;
String[] Names;

Sizing Arrays

There are three ways to set the size of arrays. Two of them require the use of the new operator. Using the new operator initializes all of the array elements to a default value. The third method involves filling in the array elements with values as you declare it.

The first method involves taking a previously declared variable and setting the size of the array. Here are a few examples:

int intArray[];         // Declare the arrays
String Names[];

intArray[] = new int[10];       // Size each array
Names[] = new String[100];

Or, you can size the array object when you declare it:

int intArray[] = new int[10];
String Names[] = new String[100];

Finally, you can fill in the array with values at declaration time:

String Names[] = {"Tony", "Dave", "Jon", "Ricardo"};
int[] intArray = {1, 2, 3, 4, 5};

Accessing Array Elements

Now that you know how to initialize arrays, you’ll need to learn how to fill them with data and then access the array elements to retrieve the data. We showed you a very simple way to add data to arrays when you initialize them, but often this just is not flexible enough for real-world programming tasks. To access an array value, you simply need to know its location. The indexing system used to access array elements is zero-based, which means that the first value is always located at position 0. Let’s look at a little program that first fills in an array and then prints it out:

public class powersOf2 {

   public static void main(String args[]) {
      int intArray[] = new int[20];
      for (int i = 0; i < intArray.length; i++) {
         intArray[i] = 1;
         for(int p = 0; p <  i; p++) intArray[i] *= 2 ;
   }
      for (int i = 0; i < intArray.length; i++)
         System.out.println("2 to the power of " + i + " is " +
           intArray[i]);
   }
}

The output of this program looks like this:

2 to the power of 0 is 1
2 to the power of 1 is 2
2 to the power of 2 is 4
2 to the power of 3 is 8
2 to the power of 4 is 16
2 to the power of 5 is 32
2 to the power of 6 is 64
2 to the power of 7 is 128
2 to the power of 8 is 256
2 to the power of 9 is 512
2 to the power of 10 is 1024
2 to the power of 11 is 2048
2 to the power of 12 is 4096
2 to the power of 13 is 8192
2 to the power of 14 is 16384
2 to the power of 15 is 32768
2 to the power of 16 is 65536
2 to the power of 17 is 131072
2 to the power of 18 is 262144
2 to the power of 19 is 524288

So, how does the program work? We first create our array of integer values and assign it to the intArray variable. Next, we begin a loop that goes from zero to intArray.length. By calling the length method of our array, we find the number of indexes in the array. Then, we start another loop that does the calculation and stores the result in the index specified by the i variable from our initial loop.

Now that we have filled in all the values for our array, we need to step back through them and print out the result. We could have just put the print statement in the initial loop, but the approach we used gives us a chance to use another loop that references our array.

Here is the structure of an index call:

arrayName[index];

Pretty simple. If you try and use an index that is outside the boundaries of the array, a run-time error occurs. If we change the program to count to an index of 21, instead of the actual array length of 20, we would end up getting an error message like this:

java.lang.ArrayIndexOutOfBoundsException:    20
            at powersOf2.main(powersOf2.java:10)

This is a pretty common error in any programming language. You need to use some form of exception handling to watch for this problem, unless, of course, you are positive you can create code that never does this (in your dreams).

Multidimensional Arrays

Multidimensional arrays are created in Java by using arrays of arrays. Here are a few examples of how you can implement multidimensional arrays:

int    intArray[][];
String   Names[][];

We can even do the same things we did with a single dimension array. We can set the array sizes and even fill in values while we declare the arrays:

int intArray[][] = new int[10][5];
String Names[][] = new String[25][3];

int intArray[][] = {{2, 3, 4} {1, 2, 3}};
String Names[][] = {{"Jon", "Smith"}{"Tony", "Potts"}{"Dave",
  "Friedel"}};

We can also create arrays that are not “rectangular” in nature. That is, each array within the main array can have a different number of elements. Here are a few examples:

int intArray[][] = {{1, 2} {1, 2, 3} {1, 2, 3, 4}};
String Names[][] = {{"Jon", "Smith"} {"Tony","A", "Potts"} {"Dave", "H",
     "Friedel", "Jr."}};

Accessing the data in a multidimensional array is not much more difficult than accessing data in a single-dimensional array. You just need to track the values for each index. Be careful though, as you add dimensions, it becomes increasingly easy to create out of bounds errors. Here are a few examples of how you can declare multidimensional arrays, assign values, and access array elements:

int intArray[][] = new int[10][5];            // Declare the arrays
String Names[][] = new String[25][3];

intArray[0][0] = 5;      // Assign values
intArray[7][2] = 37;
intArray[7][9] = 37;     // This will cause an out of bounds error!
Names[0][0] = "Bill Gates";
// Access an array element in a Java statement
System.out.println(Names[0][0]);

Using Command-Line Arguments

Programming with command-line arguments is not a topic you’d typically expect to see in an appendix on basic data types and variable declarations. However, because we’ve been using command-line arguments with some of the sample programs we’ve been introducing, we thought it would be important to discuss how this feature works in a little more detail.

Command-line arguments are only used with Java applications. They provide a mechanism so that the user of an application can pass in information to be used by the program. Java applets, on the other hand, read in parameters using HTML tags. Command-line arguments are common with languages like C and C++, which were originally designed to work with command-line operating systems like Unix.

The advantage of using command-line arguments is that they are passed to a program when the program first starts, which keeps the program from having to query the user for more information. Command-line arguments are great for passing custom initialization data.

Passing Arguments

The syntax for passing arguments themselves to a program is extremely simple. Just start your programs as you usually would and then add any number of arguments to the end of the line, with each one separated by a space. Here is a sample call to a program named “myApp”:

Java myApp open 640 480

In this case, we are calling the Java run-time interpreter and telling it to run the class file “myApp.” We then are passing in three arguments: “open,” “640,” and “480.”

If you wanted to pass in a longer string with spaces as an argument, you could. In this case, you enclose the string in quotation marks and Java will treat it as a single argument. Here is an example:

Java myApp "Nice program!" "640x480"

Once again, the name of the program is “myApp.” This time, however, we are only sending it two arguments: “Nice program!” and “640x480.” Note that the quotes themselves are not passed, just the string between the quotes.

Reading In Arguments

Now that we know how to pass arguments, where are they stored? How can we see them in our application? If you’ll recall, all applications have a main() method. You should also notice that this method has an interesting argument structure:

public static void main(String args[]) {
      ...
}

Here, main() indicates that it takes an array named args[] of type String. Java takes any command-line arguments and puts them into the args[] string array. The array is dynamically resized to hold just the number of arguments passed, or zero if none are passed. Note that the use of the args identifier is completely arbitrary. You can use any word you want as long as it conforms to the Java naming rules. You can even get a little more descriptive, like this:

public static void main(String commandLineArgumentsArray[]) { ...

That may be a bit much, but you will never get confused as to what is in the array!

Accessing Arguments

Once we’ve passed in the arguments to an application and we know where they are stored, how do we get to them? Since the arguments are stored in an array, we can access them just like we would access strings in any other array. Let’s look at a simple application that takes two arguments and prints them out:

class testArgs {
   public static void main(String args[]) {
      System.out.println(args[0]);
      System.out.println(args[1]);
   }
}

If we use this command-line statement to run the application

java  testArgs  hello  world

we’d get this output:

hello
world

Now, try this command line:

java  testArgs  onearg

Here is the result:

onearg
java.lang.ArrayIndexOutOfBoundsException: 1
             at testArgs.main(testArgs.java:4)

What happened? Since we were only passing a single argument, the reference to args[1] is illegal and produces an error.

So, how do we stop from getting an error? Instead of calling each argument in line, we can use a for loop to step through each argument. We can check the args.length variable to see if we have reached the last item. Our new code will also recognize if no arguments have been passed and will not try and access the array at all. Enough talking, here is the code:

class testArgs {
     public static void main(String args[]) {
        for (int i = 0; i < args.length; i++) {
              System.out.println(args[i]);
      }
   }
}

Now, no matter how many arguments are passed (or none), the application can handle it.


Tip:  Indexing command-line arguments.
Don’t forget that Java arrays are zero-based, so the first command-line argument is stored at position 0, not position 1. This is different than some other languages, like C, where the first argument would be at position 1. In C, position 0 would store the name of the program.

Dealing With Numeric Arguments

One more thing we should cover here is how to deal with numeric arguments. If you remember, all arguments are passed into an array of strings, so we need to convert those values into numbers.

This is actually very simple. Each data type has an associated class that provides methods for dealing with that data type. Each of these classes has a method that creates a variable of that type from a string. Table A.9 presents a list of those methods.

Table A.9 Classes and their associated methods for handling data types.
Class Method Return
Integer parseInt(String) An integer value
Integer valueOf(String) An Integer object initialized to the value represented by the specified String
Long parseLong(String) A long value
Long valueOf(String) A Long object initialized to the value represented by the specified String
Double valueOf(String) A Double object initialized to the value represented by the specified String
Float valueOf(String) A Float object initialized to the value represented by the specified String

Make sure you understand the difference between the parse*() methods and the valueOf() methods. The parsing methods just return a value that can be plugged into a variable or used as part of an expression. The valueOf() methods return an object of the specified type that has an initial value equal to the value of the string.

/**
 * Sample Java Application
 * @author Anthony Potts
 * @version 1.0
 */
class Test extends Object { // Begin Test class
   // Define class variables
   static int i = 10;
   static final double d = 3.09;
   /*
   The main() method is automatically called when
   the program is run. Any words typed after the program
   name when it is run are placed in the args[] variable,
   which is an array of strings.
   For this program to work properly, at least one word must
   be typed after the program name or else an error will occur.
   */
   public static void main(String args[]) {
      Test thisTest = new Test(); // Create instance (object) of class
      String myName = "Anthony";
      boolean returnValue;
      System.out.println("Hello " + args[0] + " my name is " + myName);
      if(thisTest.sameName(args[0], myName)) {
         System.out.println("Your name is the same as mine!");
      } else {
         System.out.println("That's not my name!");
      }
      System.out.println("Let's count to ten....");
      for (int x = 1; x < 11; x++) {
         System.out.print(x + " ");
      }
variable declarations
while control statement
method modifier
      System.out.println("\nNow down to zero by two.");
      while ( i > -1) {
         System.out.print(i + " ");
         i -= 2;
      }
      System.out.println("\nFinally, some arithmetic:");
      thisTest.doArithmetic();
   }
   // This method compares the two names sent to it and
   // returns true if they are the same and false if they are not
   public boolean sameName(String firstName, String secondName) {
      if (firstName.equals(secondName)) {
         return true;
      } else {
         return false;
      }
   }
   // This method performs a few computations and prints the result
   public void doArithmetic(){
      i = 10;
      System.out.println(i + " * " + d + " = " + (i * d));
      System.out.println(i + " * " + d + " = " +
                        (int)(i * d) + " (Integer)");
      System.out.println(i + " / " + d + " = " + (i / d));
      System.out.println(i + " / " + d + " = " +
                        (int)(i / d) + " (Integer)");
   }
 } // End of class


Table of Contents